using System;
using System.Runtime.Serialization;

namespace Meta
{
	[Serializable]
	public class Environment : object, System.Runtime.Serialization.ISerializable {
		public Environment(UserProcedure closureArg, object[] dataArg, Environment parentArg, int snlArg)  {
			closure=closureArg;
			data=dataArg;
			parent=parentArg;
			snl=snlArg;
		}
		public readonly UserProcedure closure;
		public readonly Environment parent;
		public readonly object[] data;
		public readonly int snl;
		void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
			info.AddValue("closure", closure);
			info.AddValue("parent", parent);
			info.AddValue("data", RemoteDataPlaceholder.PlaceholderArray(data));
			info.AddValue("snl", snl);
		}

		protected Environment(SerializationInfo info, StreamingContext context) {
			parent = (Environment)info.GetValue("parent", typeof(Environment));
			data = (object[])info.GetValue("data", typeof(object[]));
			closure = (ProcedurePlaceholder)info.GetValue("closure", typeof(ProcedurePlaceholder));
			snl = info.GetInt32("snl");
		}

		public object EnvLookup(int index, int vsnl) {
			Environment env = this;
			while (!(vsnl==env.snl)) {
				env = env.parent;
			}
			if (index>=0)
				return env.data[index];
			else
				return env.closure;
		}
		public object EnvSetB(int index, int  vsnl, object newval) {
			Environment env = this;
			while (!(vsnl==env.snl)) {
				env = env.parent;
			}
			return env.data[index] = newval;
		}
	}
}
